package com.wms.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wms.dto.ItemDateDto;
import com.wms.dto.ItemSpuSkuDto;
import com.wms.dto.ItemUpdateDto;
import com.wms.dto.SkuDto;
import com.wms.mapper.BrandMapper;
import com.wms.mapper.ItemMapper;
import com.wms.mapper.ItemSkuMapper;
import com.wms.mapper.ItemSpuMapper;
import com.wms.pojo.Brand;
import com.wms.pojo.ItemSku;
import com.wms.pojo.ItemSpu;
import com.wms.pojo.PageResult;
import com.wms.service.ItemService;
import com.wms.vo.ItemEchoVo;
import com.wms.vo.ItemListVo;
import com.wms.vo.ItemSkuSpuListVo;
import com.wms.vo.SkuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private ItemSpuMapper itemSpuMapper;
    @Autowired
    private ItemSkuMapper itemSkuMapper;
    @Autowired
    private BrandMapper brandMapper;


    @Override
    public PageResult page(Integer page, Integer pageSize, String code, String title, String category) {
        PageHelper.startPage(page, pageSize);
        List<ItemListVo> list = itemMapper.page(code, title, category);
        Page<ItemListVo> listVoPage = (Page<ItemListVo>) list;
        return new PageResult(Long.valueOf(list.size()), listVoPage.getResult());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addItem(ItemDateDto dto) {
        Brand brand = Brand.builder().name(dto.getBrand()).createTime(LocalDateTime.now()).updateTime(LocalDateTime.now()).build();
        brandMapper.insert(brand);
        ItemSpu itemSpu = ItemSpu.builder().createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .brandId(brand.getId())
                .categoryId1(dto.getCategoryId().get(0))
                .categoryId2(dto.getCategoryId().get(1))
                .categoryId3(dto.getCategoryId().get(2))
                .description(dto.getDescription())
                .title(dto.getTitle())
                .subTitle(dto.getTitle())
                .supplierId(dto.getSupplierId())
                .code(dto.getCode())
                .build();
        itemSpuMapper.insert(itemSpu);
        List<SkuDto> skuList = dto.getSkuList();
        if (ObjectUtil.isEmpty(skuList)) {
            return;
        }
        ArrayList<ItemSku> list = new ArrayList<>();
        for (SkuDto skuDto : skuList) {
            ItemSku itemSku = ItemSku.builder().price(skuDto.getPrice())
                    .realPrice(skuDto.getRealPrice())
                    .code(skuDto.getSkucode())
                    .title(skuDto.getSkutitle())
                    .unit(skuDto.getUnit())
                    .productWeight(skuDto.getProductWeight())
                    .productHeight(skuDto.getProductHeight())
                    .productLength(skuDto.getProductLength())
                    .productVolume(skuDto.getProductVolume())
                    .productWidth(skuDto.getProductWidth())
                    .spuId(itemSpu.getId())
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
            list.add(itemSku);
        }
        itemSkuMapper.insert(list);
    }

    @Override
    public ItemEchoVo getItemDateById(Integer id) {
        ItemSpu itemSpu = itemSpuMapper.selectById(id);
        List<ItemSku> itemSkus = itemSkuMapper.selectList(Wrappers.<ItemSku>lambdaQuery().eq(ItemSku::getSpuId, id));
        List<SkuVo> skuVOS = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(itemSkus)) {
            for (ItemSku skus : itemSkus) {
                SkuVo skuVO = SkuVo.builder().price(skus.getPrice())
                        .realPrice(skus.getRealPrice())
                        .skucode(skus.getCode())
                        .unit(skus.getUnit())
                        .id(skus.getId())
                        .skutitle(skus.getTitle())
                        .productWidth(skus.getProductWidth())
                        .productHeight(skus.getProductHeight())
                        .productVolume(skus.getProductVolume())
                        .productWeight(skus.getProductWeight())
                        .productLength(skus.getProductLength())
                        .build();
                skuVOS.add(skuVO);
            }
        }
        Brand brand = brandMapper.selectOne(Wrappers.<Brand>lambdaQuery().eq(Brand::getId, itemSpu.getBrandId()));
        ItemEchoVo itemEchoVO = ItemEchoVo.builder().id(itemSpu.getId())
                .description(itemSpu.getDescription())
                .supplierId(itemSpu.getSupplierId())
                .title(itemSpu.getTitle())
                .brand(brand.getName())
                .code(itemSpu.getCode())
                .skuList(skuVOS)
                .categoryId(itemSpu.getCategoryId3())
                .build();
        return itemEchoVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateItemDate(ItemUpdateDto dto) {
        Brand brand = brandMapper.selectOne(Wrappers.<Brand>lambdaQuery().eq(Brand::getName, dto.getBrand())
                .orderByDesc(Brand::getUpdateTime).last("limit 1"));
        brandMapper.update(Wrappers.<Brand>lambdaUpdate().eq(Brand::getId, brand.getId())
                .set(Brand::getUpdateTime, LocalDateTime.now())
                .set(Brand::getName, dto.getBrand()));
        ItemSpu itemSpu = ItemSpu.builder().code(dto.getCode())
                .id(dto.getId())
                .title(dto.getTitle())
                .subTitle(dto.getTitle())
                .brandId(brand.getId())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .description(dto.getDescription())
                .categoryId3(dto.getCategoryId())
                .supplierId(dto.getSupplierId())
                .build();
        itemSpuMapper.updateById(itemSpu);
        itemSkuMapper.delete(Wrappers.<ItemSku>lambdaQuery().eq(ItemSku::getSpuId, dto.getId()));
        List<SkuDto> skuList = dto.getSkuList();
        if (ObjectUtil.isNotEmpty(skuList)) {
            ArrayList<ItemSku> list = new ArrayList<>();
            for (SkuDto skuDto : skuList) {
                ItemSku itemSku = ItemSku.builder().createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .unit(skuDto.getUnit())
                        .spuId(itemSpu.getId())
                        .code(skuDto.getSkucode())
                        .title(skuDto.getSkutitle())
                        .price(skuDto.getPrice())
                        .realPrice(skuDto.getRealPrice())
                        .productVolume(skuDto.getProductVolume())
                        .productWidth(skuDto.getProductWidth())
                        .productLength(skuDto.getProductLength())
                        .productHeight(skuDto.getProductHeight())
                        .productWeight(skuDto.getProductWeight())
                        .build();
                list.add(itemSku);
            }
            itemSkuMapper.insert(list);
        }
    }

    @Override
    public ItemSkuSpuListVo getItemsAllList(Integer pageSelect, Integer pageSizeSelect, String skuName, String spuCode) {
        PageHelper.startPage(pageSelect, pageSizeSelect);
        List<ItemSpuSkuDto> list = itemMapper.getItemsAllList(skuName, spuCode);
        Page<ItemSpuSkuDto> dtoPage = (Page<ItemSpuSkuDto>) list;
        return new ItemSkuSpuListVo(dtoPage.getTotal(), dtoPage.getResult());
    }

    @Override
    public PageResult getSkuByPage(String title, String code, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<ItemSku> itemSkus = itemSkuMapper.selectList(Wrappers.<ItemSku>lambdaQuery()
                .like(ObjectUtil.isNotEmpty(title), ItemSku::getTitle, title)
                .like(ObjectUtil.isNotEmpty(code), ItemSku::getCode, code));
        Page<ItemSku> p = (Page<ItemSku>) itemSkus;
        return new PageResult(p.getTotal(), p.getResult());
    }
}
